/**
 * 网络请求处理
 *
 * 注意：
 * import 和 module.exports 不能同时使用
 * 如果使用 import 可以使用 export default
 */
import axios from 'axios';
import qs from "qs";
import { checkPropTypes } from 'prop-types';
import ApiDefinitionList from './api-definition';
import baseUrlConfig from './config'

var exports = {};
Object.entries(ApiDefinitionList).forEach(([name, definition])=>{
  exports[name] = generateRequest(definition);
})

export default exports;

/**
 * 生成网络请求
 *
 * @param {Object} definition api定义 
 */
function generateRequest(definition) {
  /**
   * api请求
   * 
   * @param {Object} params 请求参数
   * @param {Bool} isServer 是否是服务端
   * @param {object} req request请求 （服务端请求传递，asyncData request 在 SSR 中不携带Cookie）
   */
  return async (params, isServer = false, req = {}) => {
    let config = {
      method: definition.method || 'get',
      timeout: 30000,
    }
    return handleRequestUrl(isServer, req)
      .then((url) => {
        config.url = url
        return handleRequestHeaders(isServer, req)
      })
      .then((headers) => {
        config.headers = headers;
        return handleRequestParams(params)
      })
      .then((tempParams) => {
        if (tempParams && tempParams.is_export) {
          downloadExcel(config, tempParams);
          throw "download excel";
        }

        if (definition.method === 'get') {
          let urlParams = qs.stringify(tempParams);
          config.url = config.url + '?' + urlParams;
        } else {
          config.data = tempParams;
        }
        return axios.request(config)
      })
      .then(res => {
        if(res.data && res.data.code == 401){
          // to do 和后台确认status code
          location.href = '/login'
        }else if( res.data && res.data.status && res.data.status >0 && res.status || res.status ==200){
          return res.data
        } else{ 
          throw error;
        }
      })
      .catch(error => {
        //todo 出错显示异常
        throw error;
      })
  }
  function downloadExcel(config,params){
    let urlParams = '';
    urlParams = qs.stringify(params);
    let url = window.location.origin + config.url + '?' + urlParams;
    window.open(url);
  }
  /**
   * 处理请求URL
   * 获取请求是否是服务端 
   * 服务端（服务端渲染请求需要全路径）
   * 1.1 获取当前环境bashUrl
   * 1.2 拼接请求地址
   * 1.3 请求地址合法性校验
   * 客户端（请求需要通过代理解决浏览器跨域问题）
   * 返回path
   */
  function handleRequestUrl(isServer = false, req = {}) {
    
    return new Promise(async function (resolve, reject) {
      if (isServer) {
        const baseUrl = baseUrlConfig[process.env.NODE_ENV];
        const url = baseUrl + definition.path;
        if (!/^http[s]?:\/{2}\S+/.test(url)) {
          reject(new Error('未配置 host, 请使用全路径，例：https://192.168.1.1:3000/path'))
        }
        resolve(url);
      } else {

        resolve(definition.path);
      }
    })
  }

  /**
   * 处理请求Header
   * 问题： asyncData request 在 SSR 中不携带Cookie， 只有在浏览器环境才会有
   * 处理方法： 
   * 1. 判断是否是服务器环境
   * 2. 服务器环境设置headers.Cookie
   * 
   */
  function handleRequestHeaders(isServer = false, req = {}) {
    return new Promise(async function (resolve, reject) {
      let headers = {};
      if (isServer && req.headers) {
        headers.Cookie = req.headers.cookie;
      } 
      resolve(headers);
    })
  }

  /**
   * 处理请求参数
   * 1. 请求参数校验
   * 2. 替换请求Url TODO
   */
  function handleRequestParams(params) {
    return new Promise(async function (resolve, reject) {
      var paramTypes = definition.params;
      try {
        checkPropTypes(paramTypes, params, 'params', 'paramTypes');
      } catch (error) {
        reject(error);
      }
      resolve(params);
    })
  }

}
